package com.example.composableexample.text

import android.widget.NumberPicker.OnValueChangeListener
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.composableexample.ui.theme.ComposableExampleTheme

@Preview
@Composable
fun WithReflectionPreview() {
    ComposableExampleTheme {
        Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
            var reflectionGap by remember {
                mutableStateOf(0.5f)
            }
            var reflectionSize by remember {
                mutableStateOf(0.0f)
            }
            val provideReflectionGap = { reflectionGap }
            val provideReflectionSize = { reflectionSize }

            val reflectionEnabled = remember {
                derivedStateOf { reflectionSize > 0.2f }
            }
            val color = animateColorAsState(
                targetValue = if (reflectionEnabled.value) MaterialTheme.colorScheme.error else LocalContentColor.current,
                animationSpec = tween(1000)
            )
            Column {
                Row(
                    modifier = Modifier
                        .weight(1f)
                        .fillMaxWidth(),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.Center
                ) {
                    Text(text = "Some ", fontSize = 36.sp)
                    WithReflection(
                        provideReflectionGap = provideReflectionGap,
                        provideReflectionSize = provideReflectionSize
                    ) {
                        Text(text = "reflected ", fontSize = 36.sp, color = color.value)
                    }
                    Text(text = "text", fontSize = 26.sp)
                }
                LabeledSlider(text = "Gap", provideValue = provideReflectionGap) {reflectionGap = it}
                LabeledSlider(text = "Size", provideValue = provideReflectionSize) {reflectionSize = it}
                Spacer(modifier = Modifier.size(16.dp))
            }
        }
    }
}

@Composable
fun LabeledSlider(
    text: String,
    provideValue: () -> Float,
    onValueChange: (Float) -> Unit
) {
    Row(
        modifier = Modifier.padding(horizontal = 32.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            text = text,
            textAlign = TextAlign.End,
            modifier = Modifier
                .padding(end = 16.dp)
                .weight(1f)
        )
        Slider(
            value = provideValue(),
            onValueChange = onValueChange,
            modifier = Modifier.weight(4f)
        )
    }
}

@Composable
fun WithReflection(
    provideReflectionGap: () -> Float,
    provideReflectionSize: () -> Float,
    content: @Composable () -> Unit
) {
    val size = remember {
        mutableStateOf(IntSize.Zero)
    }
    Box(
        modifier = Modifier
            .wrapContentSize()
            .onGloballyPositioned { size.value = it.size }
    ) {
        content()
        Box(
            modifier = Modifier
                .graphicsLayer {
                    alpha = 0.99f
                    rotationX = 180f
                    translationY =
                        size.value.height.toFloat() + (size.value.height.toFloat() * (provideReflectionGap() - 0.5f))
                }
                .drawWithContent {
                    drawContent()
                    drawRect(
                        brush = Brush.verticalGradient(
                            1 - provideReflectionSize() to Color.White,
                            1f to Color.Transparent
                        ),
                        blendMode = BlendMode.DstOut
                    )
                }
        ) {
            content()
        }

    }
}